#ifndef __ILPSTRATEGIES_H
#define __ILPSTRATEGIES_H

#include "stdstratego.h"
#include "stdsc.h"

/* Strategies */
void declarearguments(argcode_t *argcode, int arguments)
{
  int ii, jj;

  for (ii=0; ii < arguments; ii++)
  {
    if (argcode[ii].argtype == 0 || argcode[ii].argtype == 1)
    {
      if (argcode[ii].extents[0].start > argcode[ii].extents[0].end)
        error("Neighbourhood starts after it ends");

      if (argcode[ii].argtype == 0)
      {
        @declare1d(addrpointer(argcode[ii].datatype),
                  argcode[ii].id, argcode[ii].state.buffer);
      }
      else
      {

        if (argcode[ii].extents[0].start > 0 || argcode[ii].extents[0].end > 0)
          error("Recursive neighbourhood extents out of bounds");

        @declare1d(addrpointer(argcode[ii].datatype),
                  argcode[ii].id, argcode[ii].state.buffer);
      }
    }
    else
    {

      @declare(addrpointer(argcode[ii].datatype), argcode[ii].id);
      if (@dataclass(argcode[ii].datatype) == 0)
        @argcode[ii].id = &(@argcode[ii].argid).data.d;
      else if (@dataclass(argcode[ii].datatype) == 1)
        @argcode[ii].id = &(@argcode[ii].argid).data.f;
      else
        @argcode[ii].id = replace(`i`, (@argcode[ii].argid).data.b, replace(`int`, addpointer(argcode[ii].datatype), `(int) i`));
    }
  }
}

void finalizearguments(argcode_t *argcode, int arguments)
{
  int ii;

  for (ii=0; ii < arguments; ii++)
    if (argcode[ii].argtype == 0)
      BufferRemoveReference(ii);
    else if (argcode[ii].argtype == 1)
      BufferFinalize(ii);
}

void finalizearguments_direct(argcode_t *argcode, int arguments)
{
  int ii;

  for (ii=0; ii < arguments; ii++)
    if (argcode[ii].argtype == 0)
      scuBufferRemoveReference((@argcode[ii].argid).buffer);
    else if (argcode[ii].argtype == 1)
      scuBufferFinalize((@argcode[ii].argid).buffer);
}

void circlepointers(argcode_t *argcode, int arguments)
{
  int ii, jj;

  for (ii=0; ii < arguments; ii++)
    if (argcode[ii].argtype == 0 || argcode[ii].argtype == 1)
    {

      for (jj=argcode[ii].state.buffer-1; jj > 0; jj--)
        (@argcode[ii].id)[jj] = (@argcode[ii].id)[jj-1];

    }
}

#endif /* __ILPSTRATEGIES_H */
